/**
 * @author Justin Akin
 * @version Action Pals Core Library 0.1.0
 */
package com.actionpals.components.controls
{	
	import com.actionpals.base.BaseNetConnection;
	import com.actionpals.base.BaseNetStream;
	import com.actionpals.events.MetaDataEvent;
	import com.actionpals.events.NetConnectionEvent;
	import com.actionpals.events.NetStreamEvent;
	
	import flash.media.SoundTransform;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	
	public class FLVVideo extends SimpleVideo
	{	
		
	//--------------------------------------------------------------------------------
	//
	//	Protected Member Variables
	//
	//--------------------------------------------------------------------------------
	
		protected var _ns:BaseNetStream;
		protected var _nc:BaseNetConnection;
		protected var _ncCommand:String = null;
		protected var _videoPath:String;
		protected var _timeInc:int = 10;
		protected var _duration:Number;
		
	//--------------------------------------------------------------------------------
	//
	//	Constructor
	//
	//--------------------------------------------------------------------------------
		
		/**
		 * Constructor
		 */		
		public function FLVVideo( width:int = 400, height:int = 300 )
		{
			super( width, height );
		}
		
	//--------------------------------------------------------------------------------
	//
	//	Public Methods
	//
	//--------------------------------------------------------------------------------
		
		public function load( videoPath:String ):void
		{	
			_videoPath = videoPath;	
			addNC();			
		}
		
		public function start():void
		{	
			addNS();
				
			_video.attachNetStream( _ns );
			_ns.play( _videoPath );
		}
		
		public function replay():void
		{
			_ns.close();
			start();
		}
		
		public function play():void
		{
			_ns.resume();
		}
		
		public function pause():void
		{
			_ns.pause();
		}
		
		public function stop():void
		{	
			_ns.close();
			_ns = null;
			_video.clear();
			_video.attachNetStream( null );			
		}
		
		public function seek( offSet:Number ):void
		{
			_ns.seek( offSet );
		}
		
		public function fastForward():void
		{
			seek( time + timeInc );
		}
		
		public function rewind():void{
			seek( time - timeInc );
		}
		
		public function mute( val:Boolean ):void
		{	
			var percent:Number = 1;
			
			if( val ) percent = 0;
			
			volume = percent;			
		}
		
	//--------------------------------------------------------------------------------
	//
	//	Getters and Setters
	//
	//--------------------------------------------------------------------------------
		
		public function get volume():Number
		{
			return nsSoundTransform.volume;
		}
		
		public function set volume( volume:Number ):void
		{	
			var transform:SoundTransform =	new SoundTransform();
	    	
	    	if( volume < 0 || volume > 1 ) return; 
	    	
	    	transform.volume = volume;
	    	nsSoundTransform = transform;	    			
		}
		
		public function get ncCommand():String{
			return _ncCommand;
		} 
		
		public function set ncCommand( ncCommand:String ):void{
			_ncCommand = ncCommand;
		}
		
		public function get timeInc():int
		{
			return _timeInc;
		}
		
		public function set timeInc( inc:int ):void
		{
			_timeInc = inc;
		}
		
		/** NetStream Getters and Setters */
		
		/* The number of seconds of data currently in the buffer. */
		public function get bufferLength():Number
		{
			return _ns.bufferLength;
		}
		
		/* Specifies how long to buffer messages before starting to display the stream. */
		public function get bufferTime():Number
		{
			return _ns.bufferTime;
		}
		
		/* Specifies how long to buffer messages before starting to display the stream. */
		public function set bufferTime( num:Number ):void
		{
			_ns.bufferTime = num;
		}
 	 	
 	 	/* The number of bytes of data that have been loaded into the player. */
 	 	public function get bytesLoaded():uint
 	 	{
 	 		return _ns.bytesLoaded;
 	 	}
 	 	
 	 	/* The total size in bytes of the file being loaded into the player. */
 	 	public function get bytesTotal():uint
 	 	{
 	 		return _ns.bytesTotal;
 	 	}
 	 	
 	 	/* Specifies whether Flash Player should try to download a cross-domain policy file from the loaded FLV file's server before beginning to load the FLV file. */
 	 	public function get checkPolicyFile():Boolean
 	 	{
 	 		return _ns.checkPolicyFile;
 	 	}
 	 	
 	 	/* Specifies whether Flash Player should try to download a cross-domain policy file from the loaded FLV file's server before beginning to load the FLV file. */
 	 	public function set checkPolicyFile( val:Boolean ):void
 	 	{
 	 		_ns.checkPolicyFile = val;
 	 	}
 	 	
		/* Specifies the object on which callback methods are invoked. */
 	 	public function get nsClient():Object
 	 	{
 	 		return _ns.client;
 	 	}
 	 	
 	 	/* Specifies the object on which callback methods are invoked. */
 	 	public function set nsClient( tar:Object ):void
 	 	{
 	 		_ns.client = tar;
 	 	}
		
		/* The number of frames per second being displayed. */
 	 	public function get currentFPS():Number
 	 	{
 	 		return _ns.currentFPS;
 	 	}
 	 	
 	 	/* The number of seconds of data in the subscribing stream's buffer in live ( unbuffered ) mode. */
 	 	public function getLiveDelay():Number{
 	 		return _ns.liveDelay;
 	 	}

		/* The object encoding ( AMF version ) for this NetStream object. */
		public function get nsObjectEncoding():uint
		{
			return _ns.objectEncoding;
		}
		
		/* Controls sound in this NetStream object. */
		public function get nsSoundTransform():SoundTransform
		{
			return _ns.soundTransform;
		}
		
		/* Controls sound in this NetStream object. */
		public function set nsSoundTransform( transform:SoundTransform ):void
		{
			_ns.soundTransform = transform;
		}
		
		/* The position of the playhead, in seconds. */
		public function get time():Number
		{
			return _ns.time;
		}
		
		/* The position of the playhead, in seconds. */
		public function get duration():Number
		{
			return _duration ? _duration : 0;
		}
		
		/* The position of the playhead, in seconds. */
		public function get percent():Number
		{
			return time == 0 || duration == 0 ? 0 : time / duration;
		}
		
		public function set percent( value:Number ):void
		{
			if( value > 1 ) value = 1;
			if( value < 0 ) value = 0;
			var t:Number = duration * value;
			trace( t );
			seek( duration * value );
		}
		
		/** NetConnection Getters and Setters */
		
		/* Specifies the object on which callback methods are invoked. */
 	 	public function get ncClient():Object
 	 	{
 	 		return _nc.client;
 	 	}
 	 	
 	 	/* Specifies the object on which callback methods are invoked. */
 	 	public function set ncClient( tar:Object ):void
 	 	{
 	 		_nc.client = tar;
 	 	}
		
		/* Indicates whether Flash Player has connected to a server through a persistent RTMP connection ( true ) or not ( false ). */
 	 	public function get connected():Boolean
 	 	{
 	 		return _nc.connected;
 	 	}
 	 	
 	 	/* If a successful connection is made, indicates the method that was used to make it: a direct connection, the CONNECT method, or HTTP tunneling. */
 	 	public function get connectedProxyType():String
 	 	{
 	 		return _nc.connectedProxyType;
 	 	}
 	 	
 	 	/* The object encoding ( AMF version ) for this NetConnection instance. */
 	 	public function get ncObjectEncoding():uint
 	 	{
 	 		return _nc.objectEncoding;
 	 	}
 	 	
 	 	/* The object encoding ( AMF version ) for this NetConnection instance. */
 	 	public function set ncObjectEncoding( num:uint ):void
 	 	{
 	 		_nc.objectEncoding = num;
 	 	}
		
		/* Determines whether native SSL is used for RTMPS instead of HTTPS, and whether the CONNECT method of tunneling is used to connect through a proxy server. */
		public function get proxyType():String
		{
			return _nc.proxyType;
		}
		
		/* Determines whether native SSL is used for RTMPS instead of HTTPS, and whether the CONNECT method of tunneling is used to connect through a proxy server. */
		public function set proxyType( type:String ):void
		{
			_nc.proxyType = type;
		}

		/* The URI of the application server that was passed to NetConnection.connect(), if connect was used to connect to a server. */
		public function get uri():String
		{
			return _nc.uri;
		}
		
		/* Indicates whether a secure connection was made using native Transport Layer Security ( TLS ) rather than HTTPS. */
 	 	public function get usingTLS():Boolean
 	 	{
 	 		return _nc.usingTLS;
 	 	}
 	 	
 	 	public function get netStream():NetStream
 	 	{
 	 		return _ns;
 	 	}
 	 	
 	 	public function get netConnection():NetConnection
 	 	{
 	 		return _nc;
 	 	}
		
	//--------------------------------------------------------------------------------
	//
	//	Protected Methods
	//
	//--------------------------------------------------------------------------------
		 
		/* This functionality is seperated into a function so that it may be overridden */
		protected function addNC():void
		{	
			_nc = new BaseNetConnection();
			_nc.addEventListener( NetConnectionEvent.CONNECT_SUCCESS, onConnectSuccess );
			_nc.addEventListener( NetConnectionEvent.CONNECT_FAILED, onConnectFailure );
			_nc.client = this;
			_nc.connect( _ncCommand );
		}
		
		/* This functionality is seperated into a function so that it may be overridden */
		protected function addNS():void
		{	
			_ns = new BaseNetStream( _nc );
			_ns.addEventListener( MetaDataEvent.DATA_AVAILABLE, onMetaData );
			_ns.addEventListener( NetStreamEvent.PLAY_STREAM_NOT_FOUND, onStreamNotFound );
			_ns.addEventListener( NetStreamEvent.BUFFER_EMPTY, onNSEvent );
			_ns.addEventListener( NetStreamEvent.BUFFER_FLUSH, onNSEvent );
			_ns.addEventListener( NetStreamEvent.BUFFER_FULL, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PAUSE_NOTIFY, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PLAY_FAILED, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PLAY_PUBLISH_NOTIFY, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PLAY_RESET, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PLAY_START, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PLAY_STOP, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PLAY_STREAM_NOT_FOUND, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PLAY_UNPUBLISH_NOTIFY, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PUBLISH_BAD_NAME, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PUBLISH_IDLE, onNSEvent );
			_ns.addEventListener( NetStreamEvent.PUBLISH_START, onNSEvent );
			_ns.addEventListener( NetStreamEvent.RECORD_FAILED, onNSEvent );
			_ns.addEventListener( NetStreamEvent.RECORD_NO_ACCESS, onNSEvent );
			_ns.addEventListener( NetStreamEvent.RECORD_START, onNSEvent );
			_ns.addEventListener( NetStreamEvent.RECORD_STOP, onNSEvent );
			_ns.addEventListener( NetStreamEvent.SEEK_FAILED, onNSEvent );
			_ns.addEventListener( NetStreamEvent.SEEK_INVALID_TIME, onNSEvent );
			_ns.addEventListener( NetStreamEvent.SEEK_NOTIFY, onNSEvent );
			_ns.addEventListener( NetStreamEvent.UNPAUSE_NOTIFY, onNSEvent );
			_ns.addEventListener( NetStreamEvent.UNPUBLISH_SUCCESS, onNSEvent );
		}
		
	//--------------------------------------------------------------------------------
	//
	//	Event Handlers
	//
	//--------------------------------------------------------------------------------
		
		protected function onNSEvent( event:NetStreamEvent ):void
		{
			dispatchEvent( new NetStreamEvent( event.type ) );
		}
		
		protected function onMetaData( event:MetaDataEvent ):void
		{
			_duration = event.data.duration;
			play();
		}
		
		protected function onConnectSuccess( event:NetConnectionEvent ):void
		{
			start();
			pause()
		}
		
		protected function onConnectFailure( event:NetConnectionEvent ):void
		{
			
		}
		
		protected function onStreamNotFound( event:NetStreamEvent ):void
		{
			
		}		
	}	
}